﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using KingSite.Library.Security;
using System.Collections.Specialized;
using System.Configuration;
using KingSite.Library.Tools;

namespace KingSite.Library.Cache.FileCacheWrapper {
    public class FileCache  {
        public string CachePath { get; set; }

        public FileCache(string cachePath) {
            if (!Directory.Exists(cachePath)) {
                try {
                    Directory.CreateDirectory(cachePath);
                }
                catch {
                    new Exception(string.Format("创建目录{0}失败，请检查配置文件 KingSiteFileCache 节", cachePath));
                }
            }
            CachePath =cachePath;
        }

        private static FileCache defaultInstance = null;
        public static FileCache GetInstance() {
            return defaultInstance ?? (defaultInstance = GetInstance("default"));
        }

        public static FileCache GetInstance(string name) {
            FileCache c;
            if (name.Equals("default")) {
                string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cachefiles");
                c = new FileCache(path);
            }
            else {
                NameValueCollection config = ConfigurationManager.GetSection("KingSiteFileCache") as NameValueCollection;
                if (config != null && !String.IsNullOrEmpty(config.Get(name))) {
                    c = new FileCache(config.Get(name));
                }
                else {
                    throw new ConfigurationErrorsException("Unable to find KingSiteFileCache instance \"" + name + "\".");
                }
            }
            return c;
        }

        public void Add(string key, object value) {
            string path = GetFileName(key);
            using (FileStream file = File.OpenWrite(path)) {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(file, value);
            }
        }

        public object Get(string key) {
            string path = GetFileName(key);
            if (!File.Exists(path)) {
                return null;
            }
            Object item = null;
            using (FileStream file = File.OpenRead(path)) {
                var formatter = new BinaryFormatter();
                item = (Object)formatter.Deserialize(file);                
            }
            return item;
        }

        public void Remove(string key) {
            string path = GetFileName(key);
            if (File.Exists(path))
                File.Delete(path);
        }

        public void Clear() {
            DirectoryInfo dir = new DirectoryInfo(CachePath);
            foreach (FileInfo f in dir.GetFiles()) {
                File.Delete(f.FullName);
            }
        }

        private string GetFileName(string key) {
            return Path.Combine(CachePath, key);
        }
    }

}
